import type {ProFormColumnsType} from '@ant-design/pro-components';
import {
  BetaSchemaForm,
  PageContainer,
} from '@ant-design/pro-components';
import {
  Card,
  Checkbox,
  Form,
  Modal,
  Space,
  Spin,
  Tree,
  TreeDataNode,
  TreeProps,
  message,
  Button,
} from 'antd';
import React, {useRef, useState} from 'react';
import styles from './style.less'
import {PlusOutlined} from '@ant-design/icons';
import {add, del, list, treeUpdate, update} from './service';
import {useRequest} from '@umijs/max';
import {DataNode} from 'antd/es/tree';
import CustomImgUpload from "@/components/CustomImgUpload";

const handleAdd = async (value: any) => {
  const hide = message.loading('正在添加');
  // console.log(value);

  try {
    await add({
      ...value
    })
    hide();
    message.success('添加成功');
    return true;
  } catch (error) {
    hide();
    message.error('添加失败请重试！');
    return false;
  }
};

const handleTreeUpdate = async (value: any[]) => {
  const hide = message.loading('正在保存');

  try {
    await treeUpdate(value);
    hide();
    message.success('保存成功');
    return true;
  } catch (error) {
    hide();
    message.error('保存失败请重试！');
    return false;
  }
};

const handleUpdate = async (value: any) => {
  const hide = message.loading('正在保存');

  try {
    await update({
      ...value,
    });
    hide();
    message.success('保存成功');
    return true;
  } catch (error) {
    hide();
    message.error('保存失败请重试！');
    return false;
  }
};

const handleRemove = async (values: any) => {
  const hide = message.loading('正在删除');
  if (!values) return true;

  try {
    await del(values);
    hide();
    message.success('删除成功，即将刷新');
    return true;
  } catch (error) {
    hide();
    message.error('删除失败，请重试');
    return false;
  }
};

const updateTreeData = (list: DataNode[], key: React.Key, children: DataNode[]): DataNode[] =>
  list.map((node) => {
    if (node.key === key) {
      return {
        ...node,
        children,
      };
    }
    if (node.children) {
      return {
        ...node,
        children: updateTreeData(node.children, key, children),
      };
    }
    return node;
  });

export default () => {
  const [treeData, setTreeData] = useState<DataNode[]>([]);
  const [expandedKeys, setExpandedKeys] = useState<any[]>([]);
  const [editForm] = Form.useForm()
  const delChildRef = useRef(false)
  const delRelatedForm = useRef(false)
  const [currentData, setCurrentData] = useState<any>({})
  const [loadedKeys, setLoadedKeys] = useState<any>([])
  const _currentData = useRef<any>({})
  const {loading, refresh} = useRequest(() => {
    return list({
      level: 1,
      parentId: null
    });
  }, {
    onSuccess(res) {
      const ret = res?.map((item: any) => ({
        ...item,
        title: item.name,
        key: item.id
      }))
      // console.log(ret);
      setTreeData(ret)
    },
  });

  const onLoadData = async ({key, children}: any) => {
    if (children?.length) return
    const {data} = await list({
      parentId: key
    })
    setTreeData((origin) =>
      updateTreeData(origin, key, data?.map((item: any) => ({
        ...item,
        title: item?.name,
        key: item?.id
      }))),
    );
    setLoadedKeys([
      ...loadedKeys, key
    ])
  }

  const onDragEnter: TreeProps['onDragEnter'] = () => {
    // console.log('onDragEnter', info);
    // expandedKeys, set it when controlled is needed
    // setExpandedKeys(info.expandedKeys)
  };
  // console.log('treeData', treeData);

  const onDrop: TreeProps['onDrop'] = async (info) => {
    // console.log('onDrop', info);
    const data: any = [...treeData];
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]); // the drop position relative to the drop node, inside 0, top -1, bottom 1
    // console.log('dropKey', dropKey)
    // console.log('dragKey', dragKey)
    // console.log('dropPos', dropPos)
    // console.log('dropPosition', dropPosition)
    const loop = (
      data: any[],
      key: React.Key,
      callback: (node: TreeDataNode, i: number, data: TreeDataNode[]) => void,
    ) => {
      for (let i = 0; i < data.length; i++) {
        data[i].sort = i;
        if (data[i].key === key) {
          return callback(data[i], i, data);
        }
        if (data[i].children) {
          loop(data[i].children!, key, callback);
        }
      }
    };

    // Find dragObject
    let dragObj: any;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    if (!info.dropToGap) {
      // Drop on the content
      loop(data, dropKey, (item) => {
        item.children = item.children || [];
        // where to insert. New item was inserted to the start of the array in this example, but can be anywhere
        item.children.unshift(dragObj);
      });
    } else {
      let ar: TreeDataNode[] = [];
      let i: number;
      loop(data, dropKey, (_item, index, arr) => {
        ar = arr;
        i = index;
      });
      if (dropPosition === -1) {
        // Drop on the top of the drop node
        dragObj.sort = i!
        ar.splice(i!, 0, dragObj!);
      } else {
        // Drop on the bottom of the drop node
        dragObj.sort = i! + 1
        ar.splice(i! + 1, 0, dragObj!);
      }
    }

    setTreeData(data);
    // console.log('dragObj', dragObj);
    // console.log('data', data);
    await handleTreeUpdate(data);
  };

  const formCol: ProFormColumnsType<any>[] = [
    {
      title: '分类名称',
      dataIndex: 'name',
      valueType: 'text',
      formItemProps: () => {
        return {
          rules: [{required: true, message: '此项为必填项'}],
        };
      },
    },
    {
      title: '分类图片',
      dataIndex: 'imgUrl',
      valueType: 'avatar',
      renderFormItem: () => <CustomImgUpload/>,
      // formItemProps: () => {
      //   return {
      //     rules: [{ required: true, message: '此项为必填项' }],
      //   };
      // },
    },
    {
      title: '父级分类',
      dataIndex: 'parentId',
      valueType: 'treeSelect',
      initialValue: currentData?.key,
      hideInForm: !currentData?.key,
      fieldProps: {
        options: treeData,
        fieldNames: {label: 'title', value: 'key', children: 'children'},
        placeholder: "请选择上级节点",
        // loadedKeys: loadedKeys,
        // expandedKeys: expandedKeys,
      },
    }
  ]

  return (
    <PageContainer content="支持创建和设计分类字段，适合需要动态配置的场景。" className={styles.category}>
      <Card title="分类信息" bordered={false}>
        <BetaSchemaForm<any>
          key="primary"
          layoutType={'ModalForm'}
          onFinish={async (values) => {
            // console.log(values);
            const isOk = await handleAdd({
              ...values,
              imgUrl: values.imgUrl?.url,
              level: 1,
              sort: 0
            })
            if (isOk) {
              setLoadedKeys([])
              setExpandedKeys([])
              refresh()
            }
            return isOk
          }}
          modalProps={{
            destroyOnClose: true,
            title: "新增一级分类",
            width: "500px",
          }}
          trigger={<Button size={'large'} type={'link'} onClick={() => {
            setCurrentData({})
            _currentData.current = {}
          }}><PlusOutlined/> 新增一级分类</Button>}
          columns={formCol}
        />

        <Spin spinning={loading}>
          <Tree
            onExpand={(expandedKeys, {node}) => {
              setCurrentData(node)
              _currentData.current = node
              setExpandedKeys(expandedKeys)
            }}
            loadData={onLoadData}
            style={{marginTop: 10}}
            draggable
            blockNode
            onDragEnter={onDragEnter}
            onDrop={onDrop}
            treeData={treeData}
            loadedKeys={loadedKeys}
            expandedKeys={expandedKeys}
            titleRender={(record: any) => {
              return <Space size={20} className={styles.title}>
                <span>{record?.title || ''}</span>
                <Space size={12} className={styles.action}>
                  <BetaSchemaForm<any>
                    layoutType={'ModalForm'}
                    onFinish={async (values) => {
                      // console.log(values);
                      const isOk = await handleAdd({
                        ...values,
                        level: _currentData.current?.level + 1,
                        imgUrl: values.imgUrl?.url,
                      })
                      if (isOk) {
                        const oldExpandedKeys = [...expandedKeys]
                        setLoadedKeys([])
                        setExpandedKeys([])
                        refresh()
                        requestIdleCallback(() => {
                          setExpandedKeys(oldExpandedKeys)
                        })
                      }
                      return isOk
                    }}
                    modalProps={{
                      destroyOnClose: true,
                      title: "新增分类",
                      width: "500px",
                    }}
                    trigger={<a onClick={() => {
                      setCurrentData(record)
                      _currentData.current = record
                    }}>
                      {/* <PlusOutlined />  */}
                      新增
                    </a>}
                    columns={formCol}
                  />
                  <BetaSchemaForm<any>
                    layoutType={'ModalForm'}
                    form={editForm}
                    onFinish={async (values) => {
                      const isOk = await handleUpdate({
                        ...values,
                        id: record?.id,
                        level: values?.parentId ? -1 : 1,
                        parentId: values?.parentId === null ? -1 : values?.parentId,
                        imgUrl: values.imgUrl?.url,
                      })
                      if (isOk) {
                        setLoadedKeys([])
                        refresh()
                      }
                      return isOk
                    }}
                    modalProps={{
                      destroyOnClose: true,
                      title: "编辑分类",
                      width: "500px",
                    }}
                    trigger={<a onClick={() => {
                      // console.log(record);
                      setCurrentData({
                        ...record,
                        parentId: record?.parentId === -1 ? null : record?.parentId,
                      })
                      _currentData.current = {
                        ...record,
                        parentId: record?.parentId === -1 ? null : record?.parentId,
                      }
                      editForm.setFieldsValue({
                        name: record?.title,
                        parentId: record?.parentId === -1 ? null : record?.parentId,
                        imgUrl: record?.imgUrl
                      })
                    }}>
                      {/* <PlusOutlined />  */}
                      编辑
                    </a>}
                    columns={formCol}
                  />
                  <a onClick={() => {
                    Modal.confirm({
                      title: `删除分类`,
                      content: <Space direction='vertical'>
                        <div>确定删除<b> {record?.title} </b>分类吗？</div>
                        <div>
                          <Checkbox onChange={(e) => {
                            delChildRef.current = e.target.checked
                          }}>同时删除子分类</Checkbox>
                        </div>
                        <div>
                          <Checkbox onChange={(e) => {
                            delRelatedForm.current = e.target.checked
                          }}>同时删除关联表格</Checkbox>
                        </div>
                      </Space>,
                      okText: '确认',
                      cancelText: '取消',
                      onOk: async () => {
                        const isOk = await handleRemove({
                          idList: [record.id],
                          delChild: delChildRef.current,
                          delForm: delRelatedForm.current,
                        })
                        if (isOk) {
                          setLoadedKeys([])
                          refresh()
                        }
                        return isOk
                      },
                    });
                  }}>删除</a>
                </Space>
              </Space>
            }}
          />
        </Spin>

      </Card>
    </PageContainer>
  );
};
